package zzs.generalframework.util.core.bytee;

import java.io.UnsupportedEncodingException;

import zzs.generalframework.util.common.constant.CharsetConstant;
import zzs.generalframework.util.common.exception.UtilException;
import zzs.generalframework.util.core.string.StringUtils;

/**
 * @title
 * @description
 * @project zzs-util
 * @package zzs.generalframework.util.core.bytee
 * @author zzs
 * @date 2018年1月30日
 * @version 1.0
 */
public class ByteUtils
{

	/**
	 * 截取字节数组
	 * 
	 * @param srcByteArray
	 *            源字节数组
	 * @param startPos
	 *            起始位置
	 * @param length
	 *            截取长度
	 * @return 返回截取字节数组
	 */
	public static byte[] cutByte(byte[] srcByteArray, int startPos, int length)
	{
		byte[] returnByteArray = null;
		if (srcByteArray == null || srcByteArray.length == 0)
		{
			returnByteArray = new byte[0];
		}
		else
		{
			if (startPos < 0)
			{
				startPos = 0;
			}
			if (length < 0)
			{
				length = 0;
			}
			else
			{
				int endPos = startPos + length;
				if (endPos > srcByteArray.length)
				{
					length = srcByteArray.length - startPos;
				}
				returnByteArray = new byte[length];
				System.arraycopy(srcByteArray, startPos, returnByteArray, 0, length);
			}
		}
		return returnByteArray;
	}

	/**
	 * 截取字节数组
	 * 
	 * @param srcByteArray
	 *            源字节数组
	 * @param startPos
	 *            起始位置
	 * @return
	 */
	public static byte[] split(byte[] srcByteArray, int startPos)
	{
		byte[] returnByteArray = null;
		if (srcByteArray == null || srcByteArray.length == 0)
		{
			returnByteArray = new byte[0];
		}
		else
		{
			if (startPos < 0)
			{
				startPos = 0;
			}
			int length = srcByteArray.length - startPos;
			returnByteArray = new byte[length];
			System.arraycopy(srcByteArray, startPos, returnByteArray, 0, length);
		}
		return returnByteArray;
	}

	/**
	 * 获取字节数组
	 * 
	 * @param srcString
	 * @param charsetName
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static byte[] getByteArray(String srcString, String charsetName) throws UnsupportedEncodingException
	{
		byte[] returnByteArray = null;
		returnByteArray = srcString.getBytes(charsetName);
		return returnByteArray;
	}

	/**
	 * 获取字节数组
	 * 
	 * @param srcString
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static byte[] getByteArray(String srcString) throws UnsupportedEncodingException
	{
		byte[] returnByteArray = null;
		returnByteArray = getByteArray(srcString, CharsetConstant.CHARSET_DEFAULT);
		return returnByteArray;
	}

	/**
	 * 
	 * @param byteArray
	 * @param lineSize
	 * @param printFlag
	 *            打印标记：右起向左,第一位:打印行号,第二位:打印内容,第三位:打印内容翻译
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String byteArray2HexTable(byte[] byteArray, int lineSize, int printFlag) throws UnsupportedEncodingException
	{
		StringBuffer returnStringBuffer = new StringBuffer();

		if (byteArray == null || byteArray.length == 0)
		{

		}
		else
		{
			int byteArrayLength = byteArray.length;
			int lineCount = byteArrayLength / lineSize;
			if (byteArrayLength % lineSize != 0)
			{
				lineCount++;
			}
			for (int lineNumber = 0; lineNumber < lineCount; lineNumber++)
			{
				int startPos = lineNumber * lineSize;
				// 行号
				int printFlagLineNumber = printFlag & 1;
				if (1 == printFlagLineNumber)
				{
					String lineNumberStr = Integer.toString(startPos, 16);
					int len = lineNumberStr.length();
					for (int i = 0; i < 8 - len; i++)
					{
						returnStringBuffer.append("0");
					}
					returnStringBuffer.append(lineNumberStr);
					returnStringBuffer.append("H:");
				}

				// 报文二进制转16进制
				int printFlagContent = printFlag & 2;
				if (2 == printFlagContent)
				{
					StringBuffer contentBuffer = new StringBuffer();
					byte[] lineByteArray = cutByte(byteArray, startPos, lineSize);
					for (int pos = 0; pos < lineByteArray.length; pos++)
					{
						String content = Integer.toHexString(lineByteArray[pos] & 0xFF);
						if (content.length() < 2)
						{
							contentBuffer.append("0");
						}
						contentBuffer.append(content);
						contentBuffer.append(" ");
					}
					returnStringBuffer.append(StringUtils.formatStr(contentBuffer.toString(), " ", lineSize * 3));
					returnStringBuffer.append(";");
				}

				int printFlagConv = printFlag & 4;
				if (4 == printFlagConv)
				{
					StringBuffer convBuffer = new StringBuffer();
					for (int pos = startPos; pos < startPos + lineSize && pos < byteArrayLength;)
					{
						// 0x1110XXXX 占用三个字节的数据
						if ((byteArray[pos] & 0xE0) == 0xE0)
						{
							String convStr = new String(cutByte(byteArray, pos, 3), "UTF-8");
							convBuffer.append(convStr);
							pos += 3;
						}
						// 0x110XXXXX 占用两个字节的数据
						else if ((byteArray[pos] & 0xC0) == 0xC0)
						{
							String convStr = new String(cutByte(byteArray, pos, 2), "UTF-8");
							convBuffer.append(convStr);
							pos += 2;
						}
						// 0x10XXXXXXXX 此为其他数据的一部分
						else if ((byteArray[pos] & 0x80) == 0x80)
						{
							convBuffer.append(".");
							pos++;
						}
						// 0x0XXXXXXX 占用一个字节的数据
						else if ((byteArray[pos] & 0x80) == 0x00)
						{
							String convStr = new String(cutByte(byteArray, pos, 1), "UTF-8");
							convBuffer.append(convStr);
							pos++;
						}
						// 其他情况
						else
						{
							convBuffer.append("*");
							pos++;
						}
					}
					returnStringBuffer.append("     ");
					returnStringBuffer.append(convBuffer);
				}
				returnStringBuffer.append("\n");
			}

		}

		return returnStringBuffer.toString();
	}

	public static String decodeByte2String(byte[] byteArray) throws UtilException
	{
		String returnString = null;
		try
		{
			returnString = new String(byteArray, "UTF-8");
		}
		catch (UnsupportedEncodingException e)
		{
			throw new UtilException(e.getMessage());
		}
		return returnString;
	}

}
